#include "../../common/etcd.hpp"
#include "../../common/channel.hpp"
#include <gflags/gflags.h>
#include <thread> 
#include "main.pb.h"

DEFINE_bool(run_mode, false, "程序的运行模式, false-调试模式, true-发布模式");
DEFINE_string(log_file, "", "发布模式下, 用于指定日志文件的路径");
DEFINE_int32(log_level, 0, "发布模式下, 用于指定日志的输出等级");

DEFINE_string(etcd_host, "http://127.0.0.1:2379", "这是服务注册中心的地址");
DEFINE_string(base_service, "/service", "这是服务监控根目录");
DEFINE_string(call_service, "/service/echo", "这是服务监控根目录");

void online(const std::string& service_name, const std::string& service_host)
{
    LOG_DEBUG("服务{}上线, 主机信息: {}", service_name, service_host);
}

void offline(const std::string& service_name, const std::string& service_host)
{
    LOG_DEBUG("服务{}下线, 主机信息: {}", service_name, service_host);
}

int main(int argc, char* argv[])
{
    google::ParseCommandLineFlags(&argc, &argv, false);
    // 初始化日志器
    Init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);

    // 1.先构造RPC信道管理对象
    auto service_manager = std::make_shared<ServiceManager>();
    service_manager->Declared(FLAGS_call_service);
    auto put_cb = std::bind(&ServiceManager::OnServiceOnline, service_manager.get(), std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&ServiceManager::OnServiceOffline, service_manager.get(), std::placeholders::_1, std::placeholders::_2);
    // 2.构造服务发现对象
    Discovery::ptr dclient = std::make_shared<Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);
    
    while(1)
    {
        // 3.通过RPC信道管理对象, 获取提供Echo服务的服务实例列表
        auto channel = service_manager->Choose(FLAGS_call_service);
        if(!channel)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));  // 等待1s, 再重试
            return -1;
        }
        // 4.发起Echo服务的RPC调用
        example::EchoService_Stub stub(channel.get());
        example::EchoRequest request;
        request.set_message("hello, world!");
        brpc::Controller* cntl = new brpc::Controller();
        example::EchoResponse* response = new example::EchoResponse();
        stub.Echo(cntl, &request, response, nullptr);
        if(cntl->Failed())
        {
            LOG_ERROR("RPC调用失败, 错误信息: {}", cntl->ErrorText());
            delete cntl;
            delete response;
            std::this_thread::sleep_for(std::chrono::seconds(1));  // 等待1s, 再重试
            continue;
        }
        LOG_DEBUG("RPC调用成功, 响应信息: {}", response->message());
        std::this_thread::sleep_for(std::chrono::seconds(1));  // 等待1s, 再重试
    }
    return 0;
}